package com.wingsfrog.puzzle.controller;

import com.pingplusplus.Pingpp;
import com.pingplusplus.model.Charge;
import com.pingplusplus.model.Event;
import com.pingplusplus.model.Webhooks;
import com.wingsfrog.puzzle.controller.dto.request.PingxxChargeDto;
import com.wingsfrog.puzzle.modules.entity.Orders;
import com.wingsfrog.puzzle.modules.entity.User;
import com.wingsfrog.puzzle.service.OrderService;
import com.wingsfrog.puzzle.service.UserService;
import com.wingsfrog.puzzle.util.RandomUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.io.BufferedReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping(value = "pingxx")
public class PingppController {
    private static Logger logger = Logger.getLogger(PingppController.class);
    @Autowired
    UserService userService;
    @Autowired
    OrderService orderService;

    @Value("${pingxx.api.key}")
    String pingxxApiKey;

    @Value("${pingxx.app.id}")
    String pingxxAppId;

    @RequestMapping(value = "test/test/")
    public String getCharge(Map<String, String> m) {
        m.put("a", "tttt");
        return "index";
    }

    @RequestMapping(value = "charge", method = {RequestMethod.POST}, params = {"channel=wx_pub"})
    @ResponseBody
    @Transactional
    public Object getCharge(HttpServletRequest request, HttpServletResponse response,
                            @RequestBody PingxxChargeDto reqDto
    ) throws Exception {
        if (reqDto.getAmount() == null || reqDto.getChannel() == null)
            throw new Exception("");

        Pingpp.apiKey = pingxxApiKey;

        String orderNo = RandomUtil.generateOrderNo(18);
        Integer amount = reqDto.getAmount();
        String channel = reqDto.getChannel();
        String currency = "cny";
        String clientIp = request.getRemoteHost();
        String subject = reqDto.getSubject();
        String body = reqDto.getBody();

        Integer userId = (Integer) request.getSession().getAttribute("userId");
        User user = userService.get(userId);
        String openId = user.getOpenId();

        Map<String, Object> chargeParams = new HashMap<String, Object>();
        chargeParams.put("order_no", orderNo);
        chargeParams.put("amount", amount);
        Map<String, String> app = new HashMap<String, String>();
        app.put("id", pingxxAppId);
        chargeParams.put("app", app);
        chargeParams.put("channel", channel);
        chargeParams.put("currency", currency);
        chargeParams.put("client_ip", clientIp);
        chargeParams.put("subject", subject);
        chargeParams.put("body", body);

        if (channel.contains("wx")) {
            Map<String, String> extra = new HashMap<>();
            extra.put("open_id", openId);
            chargeParams.put("extra", extra);
        }

        Charge charge = Charge.create(chargeParams);
        charge.getOrderNo();

        Orders orders = new Orders();
        orders.setAmount(amount);
        orders.setChannel(channel);
        orders.setPaid((byte) 0);
        orders.setUserId(userId);
        orders.setOrderNo(charge.getOrderNo());
        orderService.save(orders);
        return charge;
    }

    @RequestMapping(value = "notify", method = {RequestMethod.POST})
    @ResponseBody
    @Transactional
    public Object doNotify(HttpServletRequest request, HttpServletResponse response) {
        try {
            request.setCharacterEncoding("UTF8");
            //获取头部所有信息
            Enumeration headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String key = (String) headerNames.nextElement();
                String value = request.getHeader(key);
                logger.error(key+" "+value);
            }
            // 获得 http body 内容
            BufferedReader reader = request.getReader();
            StringBuffer buffer = new StringBuffer();
            String string;
            while ((string = reader.readLine()) != null) {
                buffer.append(string);
            }
            reader.close();
            Event event = Webhooks.eventParse(buffer.toString());
            if ("charge.succeeded".equals(event.getType())) {
                Charge charge = (Charge)event.getData().getObject();
                Orders order = orderService.get(charge.getOrderNo());
                User user = userService.get(order.getUserId());
                Integer coins = user.getCoins() + order.getAmount();
                userService.updateCoins(user.getId(), coins);
                response.setStatus(200);
            } else if ("refund.succeeded".equals(event.getType())) {
                response.setStatus(200);
            } else {
                response.setStatus(500);
                return "err";
            }
        } catch (Exception e) {
            // 解析异步通知数据
            response.setStatus(500);
        }
        return "ok";
    }
}